package cn.zhukelili.expand;

import java.util.ArrayList;
import java.util.List;

/**
 * @Description: 场景类
 * @Auther: hongheshou
 * @Date: 2018/7/23 15:32
 */
public class Client {
    public static void main(String[] args) {
        IVisitor visitor = new Visitor();
        for (Employee emp : mockEmployee()) {
            emp.accept(visitor);
        }
        System.out.println("本公司的月工资总额是：" + visitor.getTotalSalary());
    }

    //模拟出公司的人员情况，我们可以想象这个数据是通过持久层传递过来的
    public static List<Employee> mockEmployee() {
        List<Employee> empList = new ArrayList<Employee>();
        //产生张三这个员工
        CommonEmployee zhangSan = new CommonEmployee();
        zhangSan.setJob("编写Java程序，绝对的蓝领、苦工加搬运工");
        zhangSan.setName("张三");
        zhangSan.setSalary(1800);
        zhangSan.setSex(Employee.MALE);
        empList.add(zhangSan);
        //产生李四这个员工
        CommonEmployee liSi = new CommonEmployee();
        liSi.setJob("页面美工，审美素质太不流行了！");
        liSi.setName("李四");
        liSi.setSalary(1900);
        liSi.setSex(Employee.FEMALE);
        empList.add(liSi);
        //再产生一个经理
        Manager wangWu = new Manager();
        wangWu.setName("王五");
        wangWu.setPerformance("基本上是负值，但是我会拍马屁呀");
        wangWu.setSalary(18750);
        wangWu.setSex(Employee.MALE);
        empList.add(wangWu);
        return empList;
    }
}

/*
运行结果也完全相同，那回过头来看看这个程序是怎么实现的：
● 第一，通过循环遍历所有元素。
● 第二，每个员工对象都定义了一个访问者。
● 第三，员工对象把自己作为一个参数调用访问者visit方法。
● 第四，访问者调用自己内部的计算逻辑，计算出相应的数据和表格元素。
● 第五，访问者打印出报表和数据。
事情的经过就是这个样子。那我们再来看看上面提到的数据和报表格式都会改变的情
况。首先是数据的改变，数据改了当然都要改，说不上两个方案有什么优劣；其次是报表格
式的修改，这个方案绝对是有优势的，我只要再产生一个IVisitor的实现类就可以产生一个新
的报表格式，而其他的类都不用修改，如果你用Spring开发，那就更好了，在Spring的配置
文件中使用的是接口注入，我只要把配置文件中的 ref修改一下就行了，其他的都不用修改
了！这就是访问者模式的优势所在
 */